﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Kokomo.Mirror.CliMetadata;

namespace Kokomo.PeInspector.Reflection.Disassembly
{
	/// <summary>
	/// Represents a dependency on a method from MSIL.
	/// </summary>
	public class MsilMethodDependency : MsilMemberDependency
	{
		public MethodBase GetMethodDependency()
		{
			return (MethodBase)this.GetMemberDependency();
		}

		/// <summary>
		/// Gets the usage of the method.
		/// </summary>
		/// <seealso cref="MsilMethodUsage"/>
		public MsilMethodUsage Usage { get; private set; }

		/// <summary>
		/// Initializes a new instance of <see cref="MsilMethodDependency"/>.
		/// </summary>
		/// <param name="offset">The offset of the instruction causing the dependency.</param>
		/// <param name="type">The method dependency.</param>
		/// <param name="usage">The usage of the method.</param>
		/// <seealso cref="MsilTypeUsage"/>
		private MsilMethodDependency(
			Module targetModule,
			int metadataToken,
			int offset,
			MsilMethodUsage usage
			)
			: base(targetModule, metadataToken, offset)
		{
			this.Usage = usage;
		}

		public static MsilMethodDependency FromMethod(
			MethodBase method,
			MsilMethodUsage usage,
			int offset = 0
			)
		{
			if (method == null) throw new ArgumentNullException("method");
			return new MsilMethodDependency(method.Module, method.MetadataToken, offset, usage);
		}
		public static MsilMethodDependency FromMethodRef(
			ModuleMemberReference methodRef,
			MsilMethodUsage usage,
			int offset = 0
			)
		{
			if (ModuleMemberReference.IsEmpty(methodRef)) throw new ArgumentNullException("methodRef");
			return new MsilMethodDependency(methodRef.Module, methodRef.MetadataToken, offset, usage);
		}
	}
}
